package com.atguigu.gulimall.product.service.impl;

import com.atguigu.common.constant.ProductConstant;
import com.atguigu.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.atguigu.gulimall.product.dao.AttrGroupDao;
import com.atguigu.gulimall.product.dao.CategoryDao;
import com.atguigu.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.atguigu.gulimall.product.entity.AttrGroupEntity;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.gulimall.product.vo.AttrRespVo;
import com.atguigu.gulimall.product.vo.AttrVo;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.product.dao.AttrDao;
import com.atguigu.gulimall.product.entity.AttrEntity;
import com.atguigu.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;

import static com.atguigu.common.constant.ProductConstant.AttrEnum.ATTR_TYPE_BASE;
import static com.atguigu.common.constant.ProductConstant.AttrEnum.ATTR_TYPE_SALE;

@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    AttrAttrgroupRelationDao relationDao;

    @Autowired
    AttrGroupDao attrGroupDao;

    @Autowired
    CategoryDao categoryDao;

    @Autowired
    CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        //spring家的方法，进行复制对象，必须要求两个对象属性相同，不相同的属性不会复制进来
        BeanUtils.copyProperties(attr, attrEntity);
        //1.保存基本数据
        this.save(attrEntity);
        //2.保存关联关系
        //判断是否为基本属性，如果是才进行attr_group_id的保存
        if(attr.getAttrType()== ATTR_TYPE_BASE.getCode()&&attr.getAttrGroupId()!=null){
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationDao.insert(relationEntity);
        }
    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {

        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().eq("attr_type","base".equalsIgnoreCase(type)?ATTR_TYPE_BASE.getCode():ATTR_TYPE_SALE.getCode());
        if(catelogId!=0){
            queryWrapper.eq("catelog_id",catelogId);
        }
        String key =(String)params.get("key");
        if(!StringUtils.isEmpty(key)){
            queryWrapper.and((wrapper)->{
                wrapper.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );

        //由于返回参数中要求有分类名字和分组名字，这样就需要建另一个vo
        PageUtils pageUtils = new PageUtils(page);
        //利用流式编程继续处理page数据，每一个记录都是attrEntity对象
        List<Object> resVos = page.getRecords().stream().map((attrEntity)->{
            AttrRespVo attrRespVo = new AttrRespVo();
            //1,首先把attrEntity中原本的属性赋值给vo中（除了
            //"catelogName": "手机/数码/手机", //所属分类名字
            //"groupName": "主体", //所属分组名字）
            BeanUtils.copyProperties(attrEntity, attrRespVo);

            //1.设置分类和分组的名字。利用属性和属性分组联系表 查出分组名字
            //判断是否为规格参数还是销售属性
            if("base".equalsIgnoreCase(type)){

                //先通过attrEntity中的分组id（catelogId)查到联系表中对应的联系记录 （一个AttrAttrgroupRelationEntity对象）
                AttrAttrgroupRelationEntity attrId = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
                //Long attrGroupId = attrId.getAttrGroupId();
                //先判断是否为空以及分组是否为空
                if (attrId != null &&attrId.getAttrGroupId()!=null) {
                    //通过联系对象的分组id调用属性分组的查询方法查到属性分组名
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrId.getAttrGroupId());
                    attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
                //直接查询attrEntity中的分类id，利用id查到记录
            CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
            if (categoryEntity != null) {
                //利用记录对象查询分类名
                attrRespVo.setCatelogName(categoryEntity.getName());
            }
            //返回vo对象
            return attrRespVo;
        }).collect(Collectors.toList());

        pageUtils.setList(resVos);
        return pageUtils;
    }

    /**
     * @Author:孙维
     * @Description://获取属性详情（一般用于修改回显）
     * @Date: 2021/10/23 15:24
     * @Param:[attrId]
     * @return:com.atguigu.gulimall.product.vo.AttrRespVo
     **/
    @Override
    public AttrRespVo getAttrInfo(Long attrId) {
        AttrEntity attrEntity = this.getById(attrId);
        AttrRespVo respVo = new AttrRespVo();
        BeanUtils.copyProperties(attrEntity, respVo);

        //判断为基本属性，就进行分组
        if(attrEntity.getAttrType()==ATTR_TYPE_BASE.getCode()){
            //设置分组信息
            AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
            if(relationEntity!=null) {
                respVo.setAttrGroupId(relationEntity.getAttrGroupId());
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
                if(attrGroupEntity!=null) {
                    respVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
        }
        //设置分类信息
        Long catelogId = attrEntity.getCatelogId();
        Long[] catelogPath = categoryService.findCatelogPath(catelogId);
        respVo.setCatelogPath(catelogPath);
        CategoryEntity categoryEntity = categoryDao.selectById(catelogId);
        if(categoryEntity!=null){

            respVo.setCatelogName(categoryEntity.getName());
        }


        return respVo;
    }
    /**
     * @Author:孙维
     * @Description://进行表单数据更新
     * @Date: 2021/10/23 15:28
     * @Param:[attr]
     * @return:void
     **/
    @Transactional
    @Override
    public void updateAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        this.updateById(attrEntity);

        //判断为基本属性就进行分组关联
        if(attr.getAttrType()==ATTR_TYPE_BASE.getCode()){

            //1.修改分组关联
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            attrAttrgroupRelationEntity.setAttrId(attr.getAttrId());
            Integer count = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
            if(count>0) {
                relationDao.update(attrAttrgroupRelationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attr.getAttrId()));

            }else{
                relationDao.insert(attrAttrgroupRelationEntity);
            }
        }

//        Long attrId = attr.getAttrId();
//        AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
//        if(relationEntity!=null) {
//            relationEntity.setAttrGroupId(attr.getAttrGroupId());
//        }
    }

    /**
     * @Author:孙维
     * @Description:根据分组id查找关联的所有基本属性
     * @Date: 2021/10/24 20:07
     * @Param:[attrgroupId]
     * @return:java.util.List<com.atguigu.gulimall.product.entity.AttrEntity>
     **/
    @Override
    public List<AttrEntity> getAttrRelation(Long attrgroupId) {
        List<AttrAttrgroupRelationEntity> relationEntities = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId));
        List<Long> attrIds = relationEntities.stream().map((attr) -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());

        if(attrIds==null || attrIds.size()==0){
            return null;
        }
        List<AttrEntity> attrEntities = this.listByIds(attrIds);

        return  attrEntities;

    }

    /**
     * @Author:孙维
     * @Description:获取当前分组没有关联的所有属性
     * @Date: 2021/10/25 9:48
     * @Param:[params, attrgroupId]
     * @return:com.atguigu.common.utils.PageUtils
     **/
    @Override
    public PageUtils getAttrNoRelation(Map<String, Object> params, Long attrgroupId) {
        //当前分组只能关联自己所属的分类里面的所有属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId();
        //当前分组只能关联别的的分组没有引用的属性
            //当前分类下的其他分组(之后修改成又要把自己也要算进去）
            //.ne("attr_group_id",attrgroupId)去掉
        List<AttrGroupEntity> catelogIds = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        List<Object> objectList = catelogIds.stream().map((item) -> {
            return  item.getAttrGroupId();
        }).collect(Collectors.toList());
        //这些分组关联的属性
        List<AttrAttrgroupRelationEntity> groupId = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", objectList));
        List<Object> objectList1 = groupId.stream().map(item -> {
            return  item.getAttrId();
        }).collect(Collectors.toList());
        //从当前分类的所有属性中移除这些属性-》得到剩余没有关联的
        QueryWrapper<AttrEntity> attrEntityQueryWrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).eq("attr_type",ATTR_TYPE_BASE.getCode());
        if(objectList1!=null&&objectList1.size()>0){
            attrEntityQueryWrapper.notIn("attr_id", objectList1);
        }
        String key = (String)params.get("key");
        if(!StringUtils.isEmpty(key)){
            attrEntityQueryWrapper.and((w)->{
                w.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), attrEntityQueryWrapper);

        PageUtils pageUtils = new PageUtils(page);
        return pageUtils;
    }

}